package com.zl.learning.classloader;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * 加载manager的工厂
 * @author zhaolei
 *
 */
public class ManagerFactory {

	//记录热加载类的加载信息
	private static final Map<String,LoadInfo> loadTimeMap = new HashMap<String,LoadInfo>();
	//要加载的类的classpath
	public static final String CLASS_PATH = "D:\\workspace\\IdeaProjects\\Test\\JavaNotes\\target\\classes";
	
	//实现热加载的类的全名称（包名+类名）;
	public static final String MY_MANAGER = "class_loader.MyManager";
	
	public static BaseManager getManager(String className) {
		File loadFile = new File(CLASS_PATH+className.replace(".","/")+".class");
		long lastModifiled = loadFile.lastModified();
		
		System.out.println(loadFile+"--->"+lastModifiled);
		//loadTimeMap不包含className为key的LoadInfo信息。说明这个类没有加载。
		if(loadTimeMap.get(className)==null) {
			load(className,lastModifiled);
		}//加载类的时间戳变化了，我们同样要重新加这个类到jvm
		else if(loadTimeMap.get(className).getLoadTime()!= lastModifiled) {
			load(className,lastModifiled);
		}
		System.out.println(loadTimeMap.get(className).getLoadTime());
		System.out.println("---------------------");
		return loadTimeMap.get(className).getManger();
	}

	private static void load(String className, long lastModifiled) {
		MyClassLoader myClassLoader = new MyClassLoader(CLASS_PATH);
		Class<?> loadClass = null;
		try {
			loadClass = myClassLoader.loadClass(className);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		BaseManager manger = newInstance(loadClass);
		LoadInfo loadInfo = new LoadInfo(myClassLoader,lastModifiled);
		loadInfo.setManger(manger);
		loadTimeMap.put(className, loadInfo);
	}

	//以反射的方式创建BaseManager子类对象
	private static BaseManager newInstance(Class<?> loadClass) {
		// TODO Auto-generated method stub
		try {
			return (BaseManager) loadClass.getConstructor(new Class[]{}).newInstance(new Object[]{});
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
